package com.h819.core.db;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.DbUtils;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

import static java.lang.System.out;

/**
 * @Title: DataSourceUtils.java
 * @Description: TODO(数据源工具类，使用的时候需要首先调用初始化方法，使类变量获得数值)
 * @author H819
 * @date 2010-3-17
 * @version V1.0
 */
public class DataSourceUtils {

	private static DataSource dataSource = null;
	private static InitialContext ctx = null;
	private static Connection conn = null;

	/**
	 * 静态类，提供静态方法，不允许实例化
	 */
	private DataSourceUtils() {
	}

	/**
	 * 用于初始化 web 应用的数据源，配置参数已经在配置文件中配置好
	 * 
	 * @param dataSourceName
	 *            为 配置文件中的 data source name,不包含 / ，如 jdbc/MySqlPoolDS
	 */
	public static void initDataSource(String dataSourceName) {

		if (ctx == null)
			try {
				ctx = new InitialContext();
			} catch (NamingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

		if (dataSource == null) {
			try {
				dataSource = (DataSource) ctx.lookup("java:comp/env/"
						+ dataSourceName);
			} catch (NamingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 用于初始化桌面 应用的数据源，配置参数已经在配置文件中配置好
	 * 
	 * @param config
	 *            用 com.h819.core.commons.Configurations 获取的配置变量
	 * @return
	 */
	// 该方法没有完成，以后写好配置文件，在完成方法 ???
	public static void initDataSource(PropertiesConfiguration config) {
		if (dataSource == null) {
			BasicDataSource ds = new BasicDataSource();
			ds.setDriverClassName(config.getString(""));
			ds.setUrl(config.getString(""));
			ds.setUsername(config.getString(""));
			ds.setPassword(config.getString(""));

			// ds.setDriverClassName("com.mysql.jdbc.Driver");
			// ds.setUrl("jdbc:mysql://127.0.0.1:3306/test");
			// ds.setUsername("root");
			// ds.setPassword("123456");
			dataSource = ds;
		}
	}

	/**
	 * 获取数据源
	 * 
	 * @return
	 */
	public static DataSource getDataSource() {
		return dataSource;
	}

	/**
	 * 获取连接
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		if (conn == null)
			try {
				return dataSource.getConnection();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		return conn;
	}

	/**
	 * 在数据源方式中，关闭连接，仅是释放连接，不是真正关闭，而是把连接放回到连接池中。而在 jdbc 方式中，应该是真正关闭和数据库了连接
	 * 
	 * @param conn
	 */
	public static void closeConnection(Connection conn) {
		try {
			DbUtils.close(conn);
		} catch (SQLException e) {
			DbUtils.printStackTrace(e);
		}
	}

	/**
	 * 关闭数据源所有的数据库连接，相当于释放了所有资源。不能再从此数据源获取连接
	 * 
	 * @param ds
	 * @throws SQLException
	 */
	public static void shutdownDataSource(DataSource ds) {
		BasicDataSource bds = (BasicDataSource) ds;
		try {
			bds.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 打印数据源信息(不知道为什么，在 tomcat配置数据源，(BasicDataSource) ds 会出现问题)
	 * 
	 * @param ds
	 */
	public static void printDataSourceStats(DataSource ds) {
		// 在 tomcat 下，下面的打印语句需要去掉
		BasicDataSource bds = (BasicDataSource) ds;
		out.println("允许的最大连接数是: " + bds.getMaxActive());
		out.println("允许的最大 idle 数是: " + bds.getMaxIdle());
		out.println("当前活跃的连接数是: " + bds.getNumActive());
		out.println("当前等待的连接数是: " + bds.getNumIdle());

		// 可以打印测试信息
		try {
			out.println(ds.getConnection());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// TODO Auto-generated method stub

		DataSourceUtils.printDataSourceStats(dataSource);

	}

}
